package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
* 瑞联
* */
@Slf4j
public class Plugin_ECARD_P025 implements ChannelService {

    @Override
    public ChannelResult QueryBalance(JSONObject apiConfig) {
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }

    @Override
    public ChannelResult Submit(JSONObject apiConfig, Map<String, Object> data) {

        try {
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            params.put("oid",data.get("ChannelOrderCode"));
            params.put("cid",apiConfig.getString("partnerNum"));
            params.put("pid",data.get("SUPProductId"));
            params.put("pn",data.get("AccountVal"));
            params.put("nb",1);
            params.put("fm",data.get("ProductPrice"));
            params.put("ru",apiConfig.getString("callbackAddress"));
            //加密
            String apiKey = apiConfig.getString("apiKey");
            String sign = generateSignatureSubmit(params, apiKey);
            params.put("sign",sign);
            String submitUrl = apiConfig.getString("SubmitUrl");

            String resultParams = sendGet(submitUrl, params);

            Map<String, String> RespMap = new HashMap<>();
            String regex = "([^&=]+)=([^&]*)";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(resultParams);
            while (matcher.find()) {
                String key = matcher.group(1);
                String value = matcher.group(2);
                RespMap.put(key, value);
            }
            String result = RespMap.get("result");
            String msg = RespMap.get("msg");

            if(result.equals("true")){
                return ChannelResult.IN_PROCESS("充值中");
            }
            if (result.equals("false")) {
                if (msg.equals("下单失败,扣款失败,稍后重试")
                        ||msg.equals("下单失败,初始化连接失败")
                        || msg.equals("下单失败,接口运行异常")
                        ||msg.equals("下单失败,写入订单失败")) {
                    return  ChannelResult.error("瑞联："+msg);
                }
            }
            return ChannelResult.FAILED("充值失败##"+msg);
        }catch (Exception e) {
            e.printStackTrace();
            log.error("瑞联提交订单接口错误：",e);
            return  ChannelResult.error("瑞联提交订单接口错误");
        }

    }
/*
*   cid	商家编号	必选
    oid	商家的订单号	必选
    sign	签名字符串	必选*/
    @Override
    public ChannelResult Query(JSONObject apiConfig, Map<String, Object> data) {

        try {
            LinkedHashMap<String,Object> queryParams = new LinkedHashMap<>();
            queryParams.put("cid",apiConfig.getString("partnerNum"));
            queryParams.put("oid",data.get("ChannelOrderCode"));
            String apiKey = apiConfig.getString("apiKey");
            String sign = generateSignatureQuery(queryParams, apiKey);
            queryParams.put("sign",sign);
            String queryUrl = apiConfig.getString("QueryUrl");
            String resultParams = sendGet(queryUrl, queryParams);

            Map<String, String> RespMap = new HashMap<>();
            String regex = "([^&=]+)=([^&]*)";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(resultParams);
            while (matcher.find()) {
                String key = matcher.group(1);
                String value = matcher.group(2);
                RespMap.put(key, value);
            }
            String result = RespMap.get("result");
            String msg = RespMap.get("msg");
            if(result.equals("true")){
                if (msg.equals("1")) {
                    return ChannelResult.success("充值成功");
                }
                if (msg.equals("2")) {
                    return ChannelResult.IN_PROCESS("充值中");
                }
                if (msg.equals("0")) {
                    return ChannelResult.FAILED("充值失败");
                }
            }
            return ChannelResult.error("联讯："+msg);
        }catch (Exception e) {
            e.printStackTrace();
            log.error("瑞联查询订单接口错误：",e);
            return  ChannelResult.error("瑞联查询订单接口错误");
        }
    }

    @Override
    public ChannelResult Notify(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");
    }




    /*下单签名*/
    private static String generateSignatureSubmit(HashMap<String, Object> params, String secretKey) {
        StringBuilder paramString = new StringBuilder();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            paramString.append(entry.getValue()).append("-");
        }
        paramString.append(secretKey);
        String md5 = getMD5(paramString.toString());
        return md5.toLowerCase();
    }

    /*查询签名*/
    public static String generateSignatureQuery(HashMap<String, Object> params, String secretKey) {
        StringBuilder paramString = new StringBuilder();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            paramString.append(entry.getValue());
        }
        paramString.append(secretKey);
        String md5 = getMD5(paramString.toString());
        return md5.toLowerCase();
    }


    private static String getMD5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(input.getBytes());
            BigInteger number = new BigInteger(1, messageDigest);
            String hashtext = number.toString(16);
            while (hashtext.length() < 32) {
                hashtext = "0" + hashtext;
            }
            return hashtext;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String sendGet(String url, Map<String,Object> param) {
        String result = "";
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        StringBuffer params = new StringBuffer();
        param.forEach((key, value) -> {
            if (!StringUtils.isEmpty(params.toString()))
            {
                params.append("&");
            }
            try{
                params.append(URLEncoder.encode(key, "utf-8")+"=" + URLEncoder.encode(String.valueOf(value), "utf-8"));
            }catch (Exception e){
                e.printStackTrace();
            }
        });
        log.info("Http Get请求："+url+"?"+param.toString());
        HttpGet httpGet = new HttpGet(url+"?"+params.toString());
        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
            httpGet.setHeader("Content-Type", "application/json;charset=utf8");
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpGet);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                result= EntityUtils.toString(responseEntity);
                System.out.println("响应内容为:" + result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return  result;
    }

}
